/*  
 * Copyright 2007-208 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ 
import java.awt.*   
import javax.swing.* 
import javax.swing.table.*
import com.cassevern.grails.util.*

fieldNameConvList = [
                     [from:'%', to:'Pct'],
                     [from:'#', to:'No'],
                     [from:'\'', to:''],
                     [from:'\\?', to:'Question'],
                     [from:'-', to:'_'],
                     [from:'=', to:'_'],
                     [from:'/', to:'_'],
                     [from:',', to:''],
                     [from:'\\.', to:'']
                    ]


swing = new groovy.swing.SwingBuilder()
build = swing.action(
  name:'Build',
  closure:this.&build400GrailsDomainRRN, 
  mnemonic:'R'   
)
addFieldConvItem = swing.action(
  name:'Add field name character conversion item',
  closure:this.&addFieldConvItem, 
  mnemonic:'A'   
)

def errorPanel = {
	swing.panel(constraints: BorderLayout.NORTH) {
		textField(id:'error', columns:50, editable:false, '') 
	}
}
def buttonPanel = {
	swing.panel(constraints: BorderLayout.SOUTH) {
	    button(text:'Build', action:build)
	    button(text:'Add Field Conv Item', action:addFieldConvItem)
	}
}
def inputPanel = {
	swing.panel(constraints: BorderLayout.CENTER, layout: new FlowLayout()) {
		panel(layout: new GridLayout(5, 2, 5, 5)) {
		    label(text:'IP Address:', horizontalAlignment: JLabel.RIGHT)
		    textField(id:'ip', columns:15, '')
		    label(text: ' Library:', horizontalAlignment: JLabel.RIGHT)
		    textField(id:'lib', columns:10, '')
		    label(text: ' User:', horizontalAlignment: JLabel.RIGHT)
		    textField(id:'user', columns:10, '')
		    label(text: ' Password:', horizontalAlignment: JLabel.RIGHT)
		    passwordField(id:'pass', columns:10, '')
		    label(text: ' File:', horizontalAlignment: JLabel.RIGHT)
		    textField(id:'file', columns:15, '')
		    label(text: ' Domain name:', horizontalAlignment: JLabel.RIGHT)
		    textField(id:'domainName', columns:15, '')
		    label(text:'Copy to project:', horizontalAlignment: JLabel.RIGHT)
		    comboBox(id:'projectName', items:getProjectNames())
		    label(text:'Use RRN as id/key:', horizontalAlignment: JLabel.RIGHT)
		    checkBox(id:'userrn', selected:false)
		    label(text:'Verbose output:', horizontalAlignment: JLabel.RIGHT)
		    checkBox(id:'verbose', selected:true)
		}
		scrollPane {
			table(id:'table') {
				tableModel(id:'tableModel', list:fieldNameConvList) {
					propertyColumn(header: 'From col head/text char', propertyName:'from');
					propertyColumn(header: 'To domain attribute name substring', propertyName:"to");
				}
			}
		}
	} // close swing.panel
} // close inputPanel closure
def mainPanel = {
	swing.panel(layout: new BorderLayout()) {
		errorPanel()
		inputPanel()
		buttonPanel()
	} 
}  
frame = swing.frame(title:'Build Grails Domain for a DB2/400 Table', 
		            defaultCloseOperation : WindowConstants.EXIT_ON_CLOSE) {
	mainPanel()
}
frame.pack()
frame.show()

def build400GrailsDomainRRN(event) {
	swing.error.text = ''
	
	def builder = new Build400GrailsDomain(
					ip:swing.ip.text, 
					user:swing.user.text, 
					password:swing.pass.text, 
					library:swing.lib.text, 
					file:swing.file.text, 
					domainName:swing.domainName.text, 
					verbose:swing.verbose.selected
					) 
 					
	try {
		if (swing.userrn.selected) {
			builder.runRRNBuilder(fieldNameConvList)
		} else {
			builder.runDSLMappingBuilder(fieldNameConvList)
		}
		antDeploy(swing.projectName.getSelectedItem(), swing.domainName.text, swing.userrn.selected)
		printScriptSample()
		frame.setVisible(false)
	} catch (Exception e) {
		swing.error.text = e.toString()
		e.printStackTrace()
	}
}
def addFieldConvItem(event) {
	try {
		swing.error.text = ''
		fieldNameConvList << [from:'', to:'']
		int rowCount = swing.tableModel.rowCount
		swing.tableModel.fireTableRowsInserted(rowCount, rowCount)
		swing.table.resizeAndRepaint()
	} catch (Exception e) {
		swing.error.text = e.toString()
	}
}

/* TODO consider updating DataSource.groovy */
def antDeploy (projectName, domainName, userrn) {
	if (projectName == '*NONE') {
		return
	}
	ant = new AntBuilder()
	ant.echo(message:"$domainName domain")		 
	ant.copy(todir:"../$projectName/grails-app/domain") {
		fileset(dir:'.') {include(name:"${domainName}.groovy")}
	}
	if (userrn) {
		ant.echo(message:"$domainName hbm.xml")		 
		ant.copy(todir:"../$projectName/grails-app/conf/hibernate") {
			fileset(dir:'.') {
				include(name:"${domainName}.hbm.xml")
				include(name:"hibernate.cfg.xml")
			}
		}
	}
	ant.copy(todir:"../$projectName/lib") {
		fileset(dir:'.') {include(name:"jt400.jar")}
	}
	ant.copy(todir:"../$projectName/src/templates/scaffolding") {
		fileset(dir:'./src/grails/scaffolding') {include(name:"*")} 
	}
	ant.copy(todir:"../$projectName/grails-app/taglib") {
		fileset(dir:'./src') {include(name:'CASTagLib.groovy')}
	}
	ant.copy(todir:"../$projectName/scripts") {
		fileset(dir:'./src/scripts') {include(name:'*')}
	}
	ant.echo(message:
	""" be sure to modify grails-app/conf/DataSource.groovy to specify your System i settings eg:
	dataSource {
		pooled = true
		url = "jdbc:as400://${swing.ip.text}/${swing.lib.text};libraries=${swing.lib.text},YOURLIB1,YOURLIB2"
		driverClassName = "com.ibm.as400.access.AS400JDBCDriver"
		username = "${swing.user.text}"
		password = "SECRET"
		dialect = org.hibernate.dialect.DB2400Dialect.class
	}""")
	
	ant.echo("Done")
}
def getProjectNames() {
	def projectNames = []
	curDir = new File('')  
	matcher = curDir.absolutePath =~ /\w*$/ 
	upOneDir = new File(curDir.absolutePath.replaceAll("\\\\"+matcher[0], '')) 
	upOneDir.eachDir {
		matcher = it =~ /\w*$/ 
		projectNames << matcher[0]
	}		
	projectNames.remove('metadata')
	projectNames.remove('groovycas')
	projectNames << '*NONE'
	projectNames.sort()
	return projectNames
}
def printScriptSample() {
	def script = 
	"""new com.cassevern.grails.util.Build400GrailsDomain(
	ip:\'${swing.ip.text}\', 
	user:\'${swing.user.text}\', 
	password:\'SECRET\', 
	library:\'${swing.lib.text}\', 
	file:\'${swing.file.text}\', 
	domainName:\'${swing.domainName.text}\', 
	useRRNasKey:${swing.userrn.selected},
	verbose:\'${swing.verbose.selected}\'
	)."""
	
	if (swing.userrn.selected) {
		script <<= "runRRNBuilder"
	} else {
		script <<= "runDSLMappingBuilder"
	}
	script <<= "(["   
	fieldNameConvList.each {
		script <<= '['
		def from = it.from
		def to = it.to
		
		from = from.replaceAll('\\\\', '\\\\\\\\') //	 escape regex escape
		
		script << "from:\"$from\",to:'$to'"
		script <<= '],'
	}
	script = script.toString().replaceAll(/,$/, '') //	remove trailling commas

	script <<= '])'
	println script
}
